﻿using Microsoft.Identity.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Tools.Helper
{
    /// <summary>
    /// 
    /// </summary>
    public class MicrosoftToken
    {
        #region 属性 

        public static string TokenStr { get; set; }

        public static DateTime ExpireTime { get; set; }


        //private static string ClientId = "4a1aa1d5-c567-49d0-ad0b-cd957a47f842";//注册的微软应用接口key
        private static string ClientId = "606c08a9-3324-48fb-8849-c423b84ab024";//注册的微软应用接口key
        private static string loginUrl = "https://login.microsoftonline.com/common";//登录地址
        private static string[] scopes = new string[] { "offline_access", "user.read", "Calendars.Read", "Calendars.ReadWrite", "Tasks.Read", "Tasks.ReadWrite" };//权限 
        #endregion

        #region 获取/设置token

        /// <summary>
        /// 获取/设置token
        /// </summary>
        /// <returns></returns>
        public static async Task<string> SetTokenAsync()
        {
            var tokenPath = $"{System.IO.Directory.GetCurrentDirectory()}/MicrosoftToken.txt";
            if (File.Exists(tokenPath))
            {
                var token = JsonConvert.DeserializeObject<dynamic>(CommonLib.FileHelper.FileRead(tokenPath));
                TokenStr = token.TokenStr;
                ExpireTime = token.ExpireTime;
            }

            if (string.IsNullOrEmpty(TokenStr) || ExpireTime <= DateTime.Now)
            {
                AuthenticationResult authResult = null;
                var app = PublicClientApplicationBuilder.Create(ClientId).WithAuthority($"{loginUrl}").WithDefaultRedirectUri().Build();

                var accounts = await app.GetAccountsAsync();
                var firstAccount = accounts.FirstOrDefault();

                var builder = PublicClientApplicationBuilder.Create(ClientId).WithAuthority($"https://login.microsoftonline.com/common").WithDefaultRedirectUri();
                //builder.WithWindowsBroker(true);
                var _clientApp = builder.Build();
                var accounts1 = await _clientApp.GetAccountsAsync();
                var firstAccount1 = accounts1.FirstOrDefault();


                try
                {
                    authResult = await app.AcquireTokenSilent(scopes, firstAccount).ExecuteAsync();
                }
                catch (MsalUiRequiredException ex)
                {
                    System.Diagnostics.Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");
                    try
                    {
                        authResult = await app.AcquireTokenInteractive(scopes).WithAccount(accounts.FirstOrDefault()).WithPrompt(Prompt.SelectAccount).ExecuteAsync();
                    }
                    catch (MsalException)
                    {

                    }
                }
                catch (Exception)
                {

                }
                if (authResult != null)
                {
                    TokenStr = authResult.AccessToken;
                    ExpireTime = DateTime.Now.AddHours(1);

                    //保存文件
                    CommonLib.FileHelper.FileWrite(tokenPath, JsonConvert.SerializeObject(new { TokenStr = authResult.AccessToken, ExpireTime = ExpireTime }));
                }
            }
            return "";
        }
        #endregion

        #region httpget请求

        /// <summary>
        /// httpget请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static async Task<string> GetHttpByToken(string url, string token)
        {
            var httpClient = new System.Net.Http.HttpClient();
            System.Net.Http.HttpResponseMessage response;
            try
            {
                var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);
                //Add the token in Authorization header
                request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
                response = await httpClient.SendAsync(request);
                var content = await response.Content.ReadAsStringAsync();
                return content;
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
        }
        #endregion

        #region 模拟Http请求

        /// <summary>
        /// 模拟Http请求
        /// </summary>
        /// <param name="httpUrl">请求地址 http://www.baidu.com/</param>
        /// <param name="parameters">参数:id=123@name=admin </param>
        /// <param name="Method">请求形式 post get delete put</param>
        /// <param name="encoding">请求的页面编码 uft-8,gb2312</param>
        /// <param name="contentType">设置 Content-typeHTTP 标头的值。</param>
        /// <returns></returns>
        public static string HttpRequest(string httpUrl, string parameters, string Method = "Post")
        {
            string timezone = "China Standard Time";
            //创建httpWebRequest对象
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(httpUrl);

            request.ContentType = "application/json";
            request.Method = Method.ToUpper();
            request.Headers.Add("Authorization", "Bearer " + MicrosoftToken.TokenStr);
            request.Headers.Add("Prefer", $"outlook.timezone=\"{timezone}\"");


            //填充要 post/get 的内容
            if (!string.IsNullOrEmpty(parameters))
            {
                byte[] data = Encoding.GetEncoding("utf-8").GetBytes(parameters);
                request.ContentLength = data.Length;
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(data, 0, data.Length);
                requestStream.Close();
            }

            //发送 post/get 请求到服务器并读取服务器返回信息
            Stream responseStream = null;
            try
            {
                responseStream = request.GetResponse().GetResponseStream();
            }
            catch (Exception ex)
            {
            }

            //读取服务器返回信息
            string result = "";
            if (responseStream != null)
            {
                StreamReader sr = null;
                //读取
                try
                {
                    sr = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
                    result = sr.ReadToEnd();
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    sr.Close();
                }
            }
            return result;
        }
        #endregion
    }
}
